package com.chao.common.util.log;

import com.alibaba.fastjson.JSONObject;
import com.chao.common.bean.IUser;
import com.chao.common.util.RequestUtile;
import com.chao.common.util.exception.SysException;
import com.chao.common.util.log.Inter;
import com.chao.common.util.reaction.ReactionCode;
import com.chao.common.util.reaction.ReactionImpl;
import com.chao.common.util.redis.SysRedis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

import static com.chao.common.util.SysConstant.ROLE;

@Component
@WebFilter(filterName = "TimerFilter",urlPatterns = "/*")
public class TimerFilter implements Filter {

    @Autowired
    private RequestMappingHandlerMapping handlerMapping;

    private static final Logger log = LoggerFactory.getLogger(TimerFilter.class);

    @Value("${server.inter}")
    private String serverInter;

    /**
     * 在这方法中进行拦截
     * @param request
     * @param response
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws IOException, ServletException {
        try {
            long start = System.currentTimeMillis();
            HttpServletRequest req = (HttpServletRequest)request;
            HttpServletResponse res = (HttpServletResponse)response;
            String servletPath = req.getServletPath();
            // 校验权限
            if(!"develop".equals(serverInter)){
                // 查询接口是否注册
                HandlerExecutionChain handlerChain = handlerMapping.getHandler(req);
                if(null == handlerChain){
                    response.setContentType("application/json; charset=UTF-8");
                    res.getWriter().println(JSONObject.toJSONString(new ReactionImpl(ReactionCode.OTHER,"接口不存在,请检查!")));
                    return;
                }
                HandlerMethod handlerMethod = (HandlerMethod) handlerChain.getHandler();
                Method method = handlerMethod.getMethod();
                Inter inter = AnnotationUtils.findAnnotation(method, Inter.class);
                if (null == inter) {
                    response.setContentType("application/json; charset=UTF-8");
                    res.getWriter().println(JSONObject.toJSONString(new ReactionImpl(ReactionCode.OTHER,"接口路径错误,请检查!")));
                }
                else {
                    //校验接口访问权限
                    ReactionImpl reaction = userPower(req,inter);
                    if(null == reaction){
                        chain.doFilter(request, response);
                    }else {
                        response.setContentType("application/json; charset=UTF-8");
                        res.getWriter().println(JSONObject.toJSONString(reaction));
                    }
                }
            }else { // 开发模式直接访问
                chain.doFilter(request, response);
            }
            log.debug("接口:{}执行时间:{}",servletPath,(System.currentTimeMillis()-start));
        }catch (Exception e){
            log.debug("请求异常:",e);
        }
    }

    /**
     * 校验用户权限
     */
    public ReactionImpl userPower(HttpServletRequest req,Inter inter){
        try {
            if("1".equals(inter.grade())){
                return null;
            }
            // 获取登录用户
            RequestUtile.getLoginUser(RequestUtile.getLoginToken(req),IUser.class);
            //关闭权限校验则 直接允许访问
            if("close".equals(serverInter)){
                return null;
            }
            return null;
        }catch (Exception e){
            if(e instanceof SysException){
                SysException e1 = (SysException) e;
                return new ReactionImpl(e1.getCode(), e1.getContent());
            }else {
                throw e;
            }
        }
    }

}
